package top.huhuiyu.springboot3.p2301.service.api.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import top.huhuiyu.springboot3.p2301.config.ApiConfigInfo;
import top.huhuiyu.springboot3.p2301.entity.api.NewsDetailResult;
import top.huhuiyu.springboot3.p2301.entity.api.NewsListResult;
import top.huhuiyu.springboot3.p2301.entity.api.NewsTypeResult;
import top.huhuiyu.springboot3.p2301.entity.api.TbDataNews;
import top.huhuiyu.springboot3.p2301.mapper.api.TbDataNewsMapper;
import top.huhuiyu.springboot3.p2301.service.api.ApiBaseService;
import top.huhuiyu.springboot3.p2301.service.api.NewsDataService;
import top.huhuiyu.springboot3.p2301.util.JsonUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
@RequiredArgsConstructor
@Slf4j
public class NewsDataServiceImpl implements NewsDataService, ApiBaseService {
    private final ApiConfigInfo apiConfigInfo;
    private final RestTemplate restTemplate;
    private final TbDataNewsMapper tbDataNewsMapper;

    @Override
    public NewsTypeResult queryNewsType() {
        sleep();
        HttpEntity<String> httpEntity = baseHttpEntity(apiConfigInfo);
        String result = restTemplate.exchange(apiConfigInfo.getNews_url().getType(), HttpMethod.GET, httpEntity, String.class).getBody();
        log.debug("新闻类型查询：{}", result);
        return JsonUtils.parse(result, NewsTypeResult.class);
    }

    @Override
    public NewsListResult queryNewsList(Integer typeId, Integer page) {
        sleep();
        HttpEntity<String> httpEntity = baseHttpEntity(apiConfigInfo);
        String url = String.format(apiConfigInfo.getNews_url().getList(), typeId, page);
        String result = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class).getBody();
        log.debug("新闻列表查询：{}", result);
        return JsonUtils.parse(result, NewsListResult.class);
    }

    @Override
    public NewsDetailResult queryNewsDetail(String newsId) {
        sleep();
        HttpEntity<String> httpEntity = baseHttpEntity(apiConfigInfo);
        String url = String.format(apiConfigInfo.getNews_url().getDetail(), newsId);
        String result = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class).getBody();
        log.debug("新闻详情查询：{}", result);
        return JsonUtils.parse(result, NewsDetailResult.class);
    }


    private List<TbDataNews> makeNews(NewsTypeResult.NewsTypeResultData type) {
        // 获取新闻分类下面的新闻列表
        List<TbDataNews> list = new ArrayList<>();
        NewsListResult result = queryNewsList(type.getTypeId(), 1);
        if (result == null || result.getData() == null) {
            return list;
        }
        // 循环查询新闻的详细内容
        List<NewsListResult.NewsListResultData> newsList = result.getData();
        for (int i = 0; i < newsList.size(); i++) {
            NewsListResult.NewsListResultData newsData = newsList.get(i);
            // 如果新闻存在就跳过
            if (checkNewsExist(newsData.getNewsId())) {
                continue;
            }
            // 新闻的基本信息
            TbDataNews tbDataNews = buildNewsBasic(type, newsData);
            // 新闻的详细内容
            buildNewsContent(tbDataNews);
            list.add(tbDataNews);
        }
        return list;
    }

    private void buildNewsContent(TbDataNews tbDataNews) {
        NewsDetailResult result = queryNewsDetail(tbDataNews.getNewsId());
        if (result == null || result.getData() == null) {
            return;
        }
        List<NewsDetailResult.NewsItemData> data = result.getData().getItems();
        // 拼接新闻的内容
        // 文本：<p>内容</p> 图片 <img src="地址">
        StringBuilder content = new StringBuilder();
        for (NewsDetailResult.NewsItemData item : data) {
            // 文本内容
            if ("text".equalsIgnoreCase(item.getType())) {
                content.append(String.format(NEWS_TEXT, item.getContent()));
            } else if ("img".equalsIgnoreCase(item.getType())) {
                content.append(String.format(NEWS_IMG, item.getImageUrl()));
            }
        }
        tbDataNews.setContent(content.toString());
    }

    private TbDataNews buildNewsBasic(NewsTypeResult.NewsTypeResultData type, NewsListResult.NewsListResultData news) {
        TbDataNews tbDataNews = new TbDataNews();
        tbDataNews.setTypename(type.getTypeName());
        tbDataNews.setTitle(news.getTitle());
        tbDataNews.setSource(news.getSource());
        tbDataNews.setDigest(news.getDigest());
        tbDataNews.setPostTime(news.getPostTime());
        tbDataNews.setNewsId(news.getNewsId());
        // 处理图片列表的问题
        StringBuilder imgList = new StringBuilder();
        if (news.getImgList() != null) {
            for (String img : news.getImgList()) {
                imgList.append(img).append(",");
            }
        }
        if (imgList.length() > 0) {
            // 去掉最后一个多余的,
            imgList.deleteCharAt(imgList.length() - 1);
        }
        tbDataNews.setImgList(imgList.toString());
        return tbDataNews;
    }

    private boolean checkNewsExist(String newsId) {
        // 检查数据库中是否已经存在对应的新闻
        QueryWrapper<TbDataNews> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("news_id", newsId);
        return tbDataNewsMapper.selectOne(queryWrapper) != null;
    }

    private List<NewsTypeResult.NewsTypeResultData> randomTypes() {
        List<NewsTypeResult.NewsTypeResultData> list = new ArrayList<>();
        // 获取随机的新闻分类
        NewsTypeResult newsTypeResult = queryNewsType();
        if (newsTypeResult == null || newsTypeResult.getData() == null) {
            return list;
        }
        // 随机排序
        Collections.shuffle(newsTypeResult.getData());
        // 取前两个
        list.addAll(newsTypeResult.getData().subList(0, 2));
        return list;
    }

    @Override
    public int makeNewsData() {
        int count = 0;
        // 获取要新闻数据分类
        List<NewsTypeResult.NewsTypeResultData> types = randomTypes();
        // 循环处理每个分类
        for (NewsTypeResult.NewsTypeResultData type : types) {
            List<TbDataNews> list = makeNews(type);
            // 添加到数据库
            for (TbDataNews tbDataNews : list) {
                count += tbDataNewsMapper.insert(tbDataNews);
            }
        }
        return count;
    }


}
